require("stategraphs/commonstates")

local function onattackedfn(inst, data)
    if inst.components.health and not inst.components.health:IsDead()
    and (not inst.sg:HasStateTag("busy") or inst.sg:HasStateTag("frozen")) then
       inst.sg:GoToState("hit")
    end
end

local function onattackfn(inst)
    if inst.components.health and not inst.components.health:IsDead()
    and (inst.sg:HasStateTag("hit") or not inst.sg:HasStateTag("busy")) then
        inst.sg:GoToState("attack")
    end
end

local actionhandlers = {
    ActionHandler(ACTIONS.HAMMER, "attack"),
}

local events=
{
    CommonHandlers.OnLocomote(true, true),
    CommonHandlers.OnDeath(),
    EventHandler("doattack", onattackfn),
    EventHandler("attacked", onattackedfn),
}

local states=
{

    State{
        name = "idle",
        tags = {"idle"},

        onenter = function(inst)
            inst.Physics:Stop()
            inst.AnimState:PlayAnimation("idle_loop")

            if inst:IsOnOcean() then
                inst.AnimState:Show("twister_water_fx")
            else
                inst.AnimState:Hide("twister_water_fx")
            end

        end,

        events =
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),
        },
    },

----------------------COMBAT------------------------

    State{
        name = "hit",
        tags = {"hit", "busy"},

        onenter = function(inst, cb)
            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end
            inst.AnimState:PlayAnimation("hit")
        end,

        events =
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("idle") end),
        },
    },

    State{
        name = "attack",
        tags = {"attack", "busy", "canrotate"},

        onenter = function(inst)
            inst.SoundEmitter:SetParameter("wind_loop", "intensity", 1)

            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end
            inst.components.combat:StartAttack()
            inst.AnimState:PlayAnimation("atk")
        end,

        onexit = function(inst)
            inst.SoundEmitter:SetParameter("wind_loop", "intensity", 0)
        end,

        timeline =
        {
            TimeEvent(4*FRAMES, function(inst)
            end),

            TimeEvent(31*FRAMES, function(inst)
            end),

            TimeEvent(33*FRAMES, function(inst)
                inst.components.combat:DoAttack()

                if inst.bufferedaction ~= nil and inst.bufferedaction.action == ACTIONS.HAMMER then
                    local target = inst.bufferedaction.target
                    inst:ClearBufferedAction()
                    if target ~= nil and
                        target:IsValid() and
                        target.components.workable ~= nil and
                        target.components.workable:CanBeWorked() and
                        target.components.workable:GetWorkAction() == ACTIONS.HAMMER
                    then
                        target.components.workable:Destroy(inst)
                    end
                end
            end),
        },

        events=
        {
            EventHandler("animover", function(inst)
                inst.sg:GoToState("idle")

            end),
        },
    },

    State{
        name = "death",
        tags = {"busy"},

        onenter = function(inst)
            TheMixer:PopMix("twister")
            if inst.components.locomotor then
                inst.components.locomotor:StopMoving()
            end

            if inst:IsOnOcean() then
                inst.AnimState:PlayAnimation("death_water")
            else
                inst.AnimState:PlayAnimation("death")
            end
        end,

        timeline =
        {
            TimeEvent(4*FRAMES, function(inst)
            end),

            TimeEvent(40*FRAMES, function(inst)
                inst.components.inventory:DropEverything(true, true)
                inst.components.lootdropper:DropLoot()
            end),

            TimeEvent(25*FRAMES, function(inst)
            end),

            TimeEvent(50*FRAMES, function(inst)
                inst:Remove()
            end),
        },
    },

----------------WALKING---------------

    State{
        name = "walk_start",
        tags = {"moving", "canrotate"},

        onenter = function(inst)
            inst.AnimState:PlayAnimation("walk_pre")
            if inst:IsOnOcean() then
                inst.AnimState:Show("twister_water_fx")
            else
                inst.AnimState:Hide("twister_water_fx")
            end

        end,

        events =
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("walk") end ),
        },
    },

    State{
        name = "walk",
        tags = {"moving", "canrotate"},

        onenter = function(inst)
            inst.AnimState:PlayAnimation("walk_loop")
            inst.components.locomotor:WalkForward()

            if inst:IsOnOcean() then
                inst.AnimState:Show("twister_water_fx")
            else
                inst.AnimState:Hide("twister_water_fx")
            end
        end,

        timeline =
        {
            TimeEvent(24*FRAMES, function(inst) end)
        },

        events=
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("walk") end ),
        },
    },

    State{
        name = "walk_stop",
        tags = {"canrotate"},

        onenter = function(inst)
            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("walk_pst")


            if inst:IsOnOcean() then
                inst.AnimState:Show("twister_water_fx")
            else
                inst.AnimState:Hide("twister_water_fx")
            end
        end,

        events=
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("idle") end ),
        },
    },

    State{
        name = "run_start",
        tags = {"moving", "running", "atk_pre", "canrotate"},

        onenter = function(inst)
            inst.CanCharge = false
            inst.components.locomotor:RunForward()
            inst.AnimState:PlayAnimation("charge_pre")

            if inst:IsOnOcean() then
                inst.AnimState:Show("twister_water_fx")
            else
                inst.AnimState:Hide("twister_water_fx")
            end

        end,

        events =
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("run") end ),
        },
    },

    State{
        name = "run",
        tags = {"moving", "running"},

        onenter = function(inst)
            inst.components.locomotor:RunForward()
            inst.AnimState:PlayAnimation("walk_loop")


            if inst:IsOnOcean() then
                inst.AnimState:Show("twister_water_fx")
            else
                inst.AnimState:Hide("twister_water_fx")
            end
        end,

        events=
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("run") end ),
        },
    },

    State{
        name = "run_stop",
        tags = {"canrotate"},

        onenter = function(inst)
            inst.SoundEmitter:SetParameter("wind_loop", "intensity", 0)

            inst.components.locomotor:StopMoving()
            inst.AnimState:PlayAnimation("walk_pst")


            if inst:IsOnOcean() then
                inst.AnimState:Show("twister_water_fx")
            else
                inst.AnimState:Hide("twister_water_fx")
            end

        end,

        events=
        {
            EventHandler("animover", function(inst) inst.sg:GoToState("idle") end ),
        },
    },
}

return StateGraph("walpurgis_night", states, events, "idle", actionhandlers)
